package org.wabson.alfresco.translations;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;

import java.util.logging.Logger;

/**
 * Load message bundle files from a ZIP/JAR file uploaded via the App Engine Blobstore.
 * 
 * @author wabson
 */
public class BlobstoreJarLoader extends AbstractJarLoader implements JarBundleLoader
{
    private BlobKey blobKey;
    
    private String fileName;
    
    @SuppressWarnings("unused")
	private static final Logger logger = Logger.getLogger(BlobstoreService.class.getName());

    /**
     * Instantiate a new blobstore JAR message loader with the given base location
     * 
     * @param jarPath
     */
    public BlobstoreJarLoader(BlobKey blobKey, String dirPath) throws BundleLoadingException
    {
        this.dirPath = dirPath;
        this.blobKey = blobKey;
        init();
    }

    /**
     * Instantiate a new blobstore JAR message loader with the given base location
     * 
     * @param jarPath
     */
    public BlobstoreJarLoader(String blobKey, String dirPath) throws BundleLoadingException
    {
        this.dirPath = dirPath;
        this.blobKey = new BlobKey(blobKey);
        init();
    }
    
    private void init() throws BundleLoadingException
    {
        if (blobKey == null)
        {
            throw new IllegalArgumentException("The blob " + blobKey.getKeyString() + " was not found");
        }
        
        try
        {
            BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
            BlobInfoFactory blobInfoFactory = new BlobInfoFactory();
            BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(blobKey);
            
            if (blobInfo == null)
            {
                throw new BundleLoadingException("Could not find information on blob " + 
                        blobKey.getKeyString() + ". Does it exist?");
            }
            else
            {
                this.fileName = blobInfo.getFilename();
            }
            
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            int chunkSize = 1024;
            long pos = 0L;
            long size=blobInfo.getSize();
            byte[] bytes;
            while(blobInfo.getSize() > pos)
            {
                long endIndex=Math.min(size, pos + chunkSize);
                bytes=blobstoreService.fetchData(blobKey, pos, endIndex);
                pos += bytes.length;

                //System.err.println("Writing " + bytes.length + " bytes");
                os.write(bytes);
            }

            //System.err.println("blob:" + size);
            //System.err.println("OS:" + os.size());
            
            InputStream jis = new ByteArrayInputStream(os.toByteArray());
            init(jis);
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace();
        }
        catch (SecurityException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    @Override
    public String toString()
    {
        return "blob " + fileName;
    }

    public String getFileName()
    {
        return fileName;
    }

    public void setFileName(String fileName)
    {
        this.fileName = fileName;
    }

	public InputStream getInputStream() throws BundleLoadingException
	{
		BlobInfoFactory blobInfoFactory = new BlobInfoFactory();
        BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(blobKey);

        if (blobInfo == null)
        {
            throw new BundleLoadingException("Blob " + blobKey.getKeyString() + " could not be found");
        }
        
        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        
        return new ByteArrayInputStream(blobstoreService.fetchData(blobKey, 0, blobInfo.getSize() - 1));
	}
}
